// ip2regionv2
package ip2region

import (
	"fmt"
	"log"

	//"net/http"
	"os"
	"strings"
	"time"
	"xlog/ip2region/xdb"
)

const (
	dbpath = "/etc/xlog/ip2region.xdb"
)

var iprg *xdb.Searcher

func init() {
	//xdb v2
	//var ip2regionDbPth = common.GetValue("ip2regionDbv2")

	if ok, _ := PathExists(); ok {
		startTime := time.Now().UnixNano()
		//iprg, err = xdb.NewWithFileOnly(ip2regionDbPth)
		cBuff, err := xdb.LoadContentFromFile(dbpath)
		if err != nil {
			log.Printf("[ERROR] init ipdata error: %s\n", err.Error())
			return
		}
		var err2 error
		iprg, err2 = xdb.NewWithBuffer(cBuff)
		if err != nil {
			fmt.Printf("[ERROR] ip2region failed to create searcher with vector index: %s\n", err2)
			return
		}
		endTime := time.Now().UnixNano()
		log.Printf("init ipdata spent:%.1f ms\n", float64(endTime-startTime)/1000000)
		defer iprg.Close()
	}
}

func PathExists() (bool, error) {
	_, err := os.Stat(dbpath)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

type IpInfo struct {
	Country  string
	Region   string
	Province string
	City     string
	ISP      string
}

func FindIp(ips string) IpInfo {
	var ipinfo IpInfo
	// if ok, _ := PathExists(); !ok {
	// 	return ipinfo
	// }
	ipstr, _ := iprg.SearchByStr(strings.TrimSpace(ips))
	//log.Println(ipstr)
	ipinfo = IpStrToJson(ipstr)
	return ipinfo
}

func IpStrToJson(ipstr string) IpInfo {
	lineSlice := strings.Split(ipstr, "|")
	ipInfo := IpInfo{}
	length := len(lineSlice)
	if length < 5 {
		for i := 0; i <= 5-length; i++ {
			lineSlice = append(lineSlice, "")
		}
	}
	ipInfo.Country = lineSlice[0]
	ipInfo.Region = lineSlice[1]
	ipInfo.Province = lineSlice[2]
	ipInfo.City = lineSlice[3]
	ipInfo.ISP = lineSlice[4]
	return ipInfo
}

func IpToCity(ip string) string {
	ipstr, err := iprg.SearchByStr(strings.TrimSpace(ip))
	if err != nil {
		return "未知"
	}
	ipinfo := IpStrToJson(ipstr)
	city := ipinfo.City
	if city == "" || city == "0" {
		region := ipinfo.Province
		if region == "" || region == "0" {
			return "未知"
		}
	}
	return city
}

func IpToRegion(ip string) string {
	ipstr, err := iprg.SearchByStr(strings.TrimSpace(ip))
	if err != nil {
		return "未知"
	}
	ipinfo := IpStrToJson(ipstr)
	city := ipinfo.Region
	if city == "" || city == "0" {
		city = ipinfo.Province
		if city == "" || city == "0" {
			return "未知"
		}
	}
	return city
}

// func GetIp(w http.ResponseWriter, r *http.Request) {
// 	r.ParseForm()
// 	startTime := time.Now().UnixNano()
// 	var ips string
// 	ips = r.Form.Get("ip")
// 	if ips == "" {
// 		if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
// 			xffarry := strings.Split(xff, ",")
// 			for i := 0; i < len(xffarry); i++ {
// 				if !(strings.HasPrefix(xffarry[i], "192.168") || strings.HasPrefix(xffarry[i], "127.0.0") || strings.HasPrefix(xffarry[i], "10.")) {
// 					ips = xffarry[i]
// 					break
// 				}
// 			}
// 			if ips == "" {
// 				ips = strings.Split(xff, ",")[0]
// 			}
// 		} else {
// 			ips = strings.Split(r.RemoteAddr, ":")[0]
// 		}
// 	}
// 	ipstr, err := iprg.SearchByStr(strings.TrimSpace(ips))
// 	endTime := time.Now().UnixNano()
// 	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
// 	w.Header().Set("Access-Control-Allow-Origin", "*")
// 	w.Header().Set("Content-Type", "application/json")
// 	//log.Printf("getip spent:%.1f ms\n", float64(endTime-startTime)/1000000)
// 	if err != nil {
// 		log.Printf("SearchIp Fail:%s\n", err)
// 		fmt.Fprintf(w, "{\"msg\":\"fail\"}")
// 		return
// 	}
// 	//log.Printf("TEST:%s", ipstr)
// 	ipinfo := IpStrToJson(ipstr)
// 	//jsonstr := fmt.Sprintf(`{"ip":"%s","region":"%s","city":"%s","isp":"%s"}`, ips, strings.Trim(ipinfo.Province, "省"), strings.Trim(ipinfo.City, "市"), ipinfo.ISP)
// 	jsonstr := fmt.Sprintf(`{"ip":"%s","country":"%s","region":"%s","city":"%s","isp":"%s"}`, strings.TrimSpace(ips), ipinfo.Country, ipinfo.Province, ipinfo.City, ipinfo.ISP)
// 	log.Printf("SearchIp Success spent:%.1f ms,result:%s\n", float64(endTime-startTime)/1000000, jsonstr)
// 	fmt.Fprintf(w, jsonstr)
// }
